VFG.EModel=function(viewer, options) {
	this.viewer = viewer;
	this.options = options;
	this.parentId= options.parentId||'';
	this.id= options.id;
	this.name= options.name||'';
	this.code= options.code||'';
	this.type= options.type||'';
	this.position=options.position||null;
	this.orientation=options.orientation||{};
	this.model=options.model||{};
	this.attribute=options.attribute||{};
	this.propertys=options.propertys||[];
	this.antennaMap=new Map();
	this.init();
}
VFG.EModel.prototype.init = function() {
	let _this=this;
	var param={
			id: this.id,
			name :this.name,
			url :this.model.url||'',
			modelMatrix : this.getModelMatrix(),
			scale :this.model.scale*1||1,
			show : this.model.show||true,   
			minimumPixelSize:this.model.minimumPixelSize||0,
			allowPicking : this.model.allowPicking||true,        
			debugShowBoundingVolume : this.model.debugShowBoundingVolume||false, 
			debugWireframe : this.model.debugWireframe||false, 
			backFaceCulling:this.model.backFaceCulling||false, 
			shadows: this.model.shadows||false,   
	}
	if('1'== this.model.distanceDisplayCondition){
		param.distanceDisplayCondition=VFG.Util.getDistanceDisplayCondition( this.model.distanceNear, this.model.distanceFar);	
	}
	if('1'== this.model.silhouette){
		param.silhouetteColor= this.model.silhouetteColor? Cesium.Color.fromCssColorString( this.model.silhouetteColor):Cesium.Color.BLACK;	
		param.silhouetteSize= this.model.silhouetteSize*1||0;	
	}
	if('1'== this.model.fill){
		param.color= this.model.fillColor? Cesium.Color.fromCssColorString( this.model.fillColor):Cesium.Color.BLACK;	
	}
	this.primity = this.viewer.scene.primitives.add(Cesium.Model.fromGltf(param));
	this.primity.readyPromise.then(function(model) {
		if(_this.success){
			_this.success(model)
		}
	}).otherwise(function(error){
		if(_this.error){
			_this.error(error);
		}
    });
	if(_this.options.antennas){
		for(var p in _this.options.antennas){
			_this.addAntenna(_this.options.antennas[p]);
		}
	}
};
VFG.EModel.prototype.getModelMatrix=function(){
    var hpRoll = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(this.orientation.heading || 0), Cesium.Math.toRadians(this.orientation.pitch || 0), Cesium.Math.toRadians(this.orientation.roll || 0));
    var fixedFrameTransform = Cesium.Transforms.eastNorthUpToFixedFrame;
    let cartesian3=Cesium.Cartesian3.fromDegrees(this.position.x*1, this.position.y*1,this.position.z*1);
    var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(cartesian3, hpRoll, this.viewer.scene.globe.ellipsoid, fixedFrameTransform);
    return modelMatrix;
}

VFG.EModel.prototype.getRadius=function(){
    return this.primity.boundingSphere.radius;
}


VFG.EModel.prototype.on=function(type,callback){
	if('success'==type){
		this.success=callback;
	}
	if('error'==type){
		this.error=callback;
	}
}

VFG.EModel.prototype.update=function(param){

	if(param.position){
		this.position=param.position;
	}
	
	if(param.orientation){
		if(this.orientation.pitch){
			this.orientation.pitch=param.orientation.pitch;
		}
		if(this.orientation.heading){
			this.orientation.heading=param.orientation.heading;
		}
		if(this.orientation.roll){
			this.orientation.roll=param.orientation.roll;
		}
	}
	
	if(this.primity){
		this.primity.modelMatrix=this.getModelMatrix();
	}
	this.updateAntennas();
}

VFG.EModel.prototype.updatePosition=function(position){
	this.position=position;
	if(this.primity){
		this.primity.modelMatrix=this.getModelMatrix();
		this.updateAntennas();
	}
}

VFG.EModel.prototype.updateAttribute=function(attribute){
	this.attribute=attribute;
	if(attribute && attribute.name){
		this.name=attribute.name;
		this.attribute.name=attribute.name;
	}
	if(attribute && attribute.parentId){
		this.parentId=attribute.parentId;
		this.attribute.parentId=attribute.parentId;
	}
	
	if(attribute && attribute.code){
		this.attribute.code=attribute.code;
		this.code=attribute.code;
	}
	if(attribute && attribute.sort){
		this.attribute.sort=attribute.sort;
	}
}

/**
 * 缩放
 */
VFG.EModel.prototype.updateScale=function(scale){
	this.model.scale=scale;
	if(this.primity){
		this.primity.scale=this.model.scale*1;
	}
}

VFG.EModel.prototype.updateHeading=function(heading){
	this.orientation.heading=heading;
	if(this.primity){
		this.primity.modelMatrix=this.getModelMatrix();
		this.updateAntennas();
	}
}

VFG.EModel.prototype.updatePitch=function(pitch){
	this.orientation.pitch=pitch;
	if(this.primity){
		this.primity.modelMatrix=this.getModelMatrix();
		this.updateAntennas();
	}
}

VFG.EModel.prototype.updateRoll=function(roll){
	this.orientation.roll=roll;
	if(this.primity){
		this.primity.modelMatrix=this.getModelMatrix();
		this.updateAntennas();
	}
}

VFG.EModel.prototype.updateMinimumPixelSize=function(minimumPixelSize){
	this.model.minimumPixelSize=minimumPixelSize;
	if(this.primity){
		this.primity.minimumPixelSize=minimumPixelSize;
	}
}

VFG.EModel.prototype.updateColor=function(color){
	this.model.fillColor=color;
	if(this.primity){
		this.primity.color=color? Cesium.Color.fromCssColorString(color):Cesium.Color.WHITE;	
	}
}

VFG.EModel.prototype.updateSilhouetteColor=function(silhouetteColor){
	this.model.silhouetteColor=silhouetteColor;
	if(this.primity){
		this.primity.silhouetteColor=silhouetteColor? Cesium.Color.fromCssColorString(silhouetteColor):Cesium.Color.WHITE;	
	}
}
VFG.EModel.prototype.updateSilhouetteSize=function(silhouetteSize){
	this.model.silhouetteSize=silhouetteSize;
	if(this.primity){
		this.primity.silhouetteSize=silhouetteSize*1;	
	}
}

VFG.EModel.prototype.updateDistanceDisplay=function(display){
	if(display.distanceNear){
		this.model.distanceNear=display.distanceNear;
	}
	if(display.distanceFar){
		this.model.distanceFar=display.distanceFar;
	}
	if(this.primity){
		this.primity.distanceDisplayCondition=VFG.Util.getDistanceDisplayCondition(this.model.distanceNear||0,this.model.distanceFar||5000);	
	}
}

VFG.EModel.prototype.isDistanceDisplay=function(display){
	this.model.distanceDisplayCondition=display;
	if(this.primity){
		if('1'===display){
			this.primity.distanceDisplayCondition=VFG.Util.getDistanceDisplayCondition(this.model.distanceNear||0,this.model.distanceFar||5000);	
		}else{
			this.primity.distanceDisplayCondition=null;	
		}
	}
}

VFG.EModel.prototype.isSilhouette=function(silhouette){
	this.model.silhouette=silhouette;
	if(this.primity){
		if('1'===silhouette){
			this.primity.silhouetteColor= this.model.silhouetteColor? Cesium.Color.fromCssColorString( this.model.silhouetteColor):Cesium.Color.WHITE;	
			this.primity.silhouetteSize= this.model.silhouetteSize*1||0;	
		}else{
			this.primity.silhouetteColor= Cesium.Color.WHITE;	
			this.primity.silhouetteSize= 0;	
		}
	}
}

VFG.EModel.prototype.isFill=function(fill){
	this.model.fill=fill;
	if(this.primity){
		if('1'===fill){
			this.primity.color= this.model.fillColor? Cesium.Color.fromCssColorString( this.model.fillColor):Cesium.Color.WHITE;	
		}else{
			this.primity.color= Cesium.Color.WHITE;	
		}
	}
}

VFG.EModel.prototype.isShadows=function(shadows){
	this.model.shadows=shadows;
	if(this.primity){
		if('1'===shadows){
			this.primity.shadows= this.model.shadows*1;	
		}else{
			this.primity.shadows= this.model.shadows*1;	
		}
	}
}

VFG.EModel.prototype.selected=function(){
	if(this.primity){
		this.primity.silhouetteColor= Cesium.Color.YELLOW;	
		this.primity.silhouetteSize= 2;	
	}
}

VFG.EModel.prototype.unselected=function(){
	if(this.primity){
		this.primity.silhouetteColor= this.model.silhouetteColor? Cesium.Color.fromCssColorString( this.model.silhouetteColor):Cesium.Color.WHITE;	
		this.primity.silhouetteSize= 0;	
	}
}

VFG.EModel.prototype.isAnimation=function(animation){
	this.model.animation=animation;
	if(this.primity){
		if('1'===animation){
			this.primity.animation= this.model.animation*1;	
		}else{
			this.primity.animation= this.model.animation*1;	
		}
	}
}

VFG.EModel.prototype.updateProperty= function(property) {
	var _this = this;
	if(_this.propertys){
		for(let index in _this.propertys){
			if(property.id==_this.propertys[index].id){
				_this.propertys.splice(index,1,property);
				return;
			}
		}
		_this.propertys.push(property);
	}
};

VFG.EModel.prototype.removeProperty= function(id) {
	var _this = this;
	if(_this.propertys){
		for(let index in _this.propertys){
			if(id==_this.propertys[index].id){
				_this.propertys.splice(index,1);
				return;
			}
		}
	}
};

VFG.EModel.prototype.addAntenna= function(param) {
	var _this = this;
	if(!_this.antennaMap.has(param.id)){
		_this.createAntenna(param);
	}else{
		this.updateAntenna(param)
	}
};

VFG.EModel.prototype.createAntenna= function(param) {
	var _this = this;
	let heading;
	if('0'==param.position){
		heading=(this.orientation.heading||0)*1+90;
	}
	else if('1'==param.position){
		heading=(this.orientation.heading||0)*1+270;
	}
	else if('2'==param.position){
		heading=(this.orientation.heading||0)*1+180;
	}
	else if('3'==param.position){
		heading=(this.orientation.heading||0)*1+0;
	}
	let tartPosition=VFG.Util.getTargetPosition({
		x:_this.position.x*1,
		y:_this.position.y*1,
		z:_this.position.z*1+(param.relativeHeight*1)
	},{
		far:param.relativeFar*1,//距离
		heading:heading*1,
		pitch:0,
	});
	if(tartPosition && tartPosition.x && tartPosition.y){
		let antenna = this.viewer.entities.add({
		  id: param.id,
		  name: param.name||'',
		  position: Cesium.Cartesian3.fromDegrees(tartPosition.x*1,tartPosition.y*1, tartPosition.z*1),
	      point: new Cesium.PointGraphics({
	          color: Cesium.Color.SKYBLUE,
	          pixelSize: param.pixelSize||5,
	          outlineColor: Cesium.Color.YELLOW,
	          outlineWidth: 3,
	      }),
		})
		_this.antennaMap.set(param.id,param)	
	}
};

VFG.EModel.prototype.updateAntenna= function(param) {
	var _this = this;
	if(_this.antennaMap.has(param.id)){
		if(param.name){
			_this.antennaMap.get(param.id).name=param.name
		}
		if(param.code){
			_this.antennaMap.get(param.id).code=param.code
		}
		if(param.relativeHeight){
			_this.antennaMap.get(param.id).relativeHeight=param.relativeHeight
		}
		if(param.position){
			_this.antennaMap.get(param.id).position=param.position
		}
/*		if(param.relativePitch){
			_this.antennaMap.get(param.id).relativePitch=param.relativePitch
		}*/
		if(param.relativeFar){
			_this.antennaMap.get(param.id).relativeFar=param.relativeFar
		}
		if(param.pixelSize){
			_this.antennaMap.get(param.id).pixelSize=param.pixelSize
		}
		if(param.heading){
			_this.antennaMap.get(param.id).heading=param.heading
		}
		if(param.pitch){
			_this.antennaMap.get(param.id).pitch=param.pitch
		}
		if(param.roll){
			_this.antennaMap.get(param.id).roll=param.roll
		}
		let antenna=_this.viewer.entities.getById(param.id);
		if(antenna){
			let heading;
			if('0'==param.position){
				heading=(this.orientation.heading||0)*1+90;
			}
			else if('1'==param.position){
				heading=(this.orientation.heading||0)*1+270;
			}
			else if('2'==param.position){
				heading=(this.orientation.heading||0)*1+180;
			}
			else if('3'==param.position){
				heading=(this.orientation.heading||0)*1+0;
			}
			
			let tartPosition=VFG.Util.getTargetPosition({
				x:_this.position.x*1,
				y:_this.position.y*1,
				z:_this.position.z*1+(param.relativeHeight*1)
			},{
				far:param.relativeFar*1,//距离
				heading:heading*1,
				pitch:0,
			});
			
			let h=VFG.Util.getHeading({
				x:_this.position.x*1,y: _this.position.y*1,z:tartPosition.z*1
			},tartPosition);
			let p=VFG.Util.getPitch({
				x:_this.position.x*1,y: _this.position.y*1,z:tartPosition.z*1
			},tartPosition);
			
			let d=VFG.Util.getSpaceDistance({
				x:_this.position.x*1,y: _this.position.y*1,z:tartPosition.z*1
			},tartPosition)
			
			 tartPosition=VFG.Util.getTargetPosition({
				x:_this.position.x*1,
				y:_this.position.y*1,
				z:_this.position.z*1+(param.relativeHeight*1)
			},{
				far:d,//距离
				heading:h*1,
				pitch:p*1+((_this.orientation.roll||0)*1),
			});
			
			console.log(tartPosition);
		//	tartPosition=_this.getRollPosition(tartPosition,(_this.orientation.roll||0)*1)
			
			
			if(tartPosition && tartPosition.x && tartPosition.y){
				antenna.name=_this.antennaMap.get(param.id).name;
				antenna.position=Cesium.Cartesian3.fromDegrees(tartPosition.x*1, tartPosition.y*1,tartPosition.z*1);
			}
		}
	}
};

VFG.EModel.prototype.removeAntenna= function(id) {
	var _this = this;
	if(_this.antennaMap.has(id)){
		_this.viewer.entities.removeById(id);
		_this.antennaMap.delete(id)
	}
};

VFG.EModel.prototype.updateAntennas= function() {
	var _this = this;
	if(this.antennaMap){
		_this.antennaMap.forEach(function (value,key){
			try{
				_this.updateAntenna(value);
			}catch (e) {
			}finally{
			}
		});
	}
};


VFG.EModel.prototype.getRollPosition=function(a,roll){
	console.log(a,roll);
	let A=Cesium.Cartesian3.fromDegrees(a.x*1, a.y*1,a.z*1)
	let B=Cesium.Cartesian3.fromDegrees(this.position.x*1, this.position.y*1,a.z*1)
	
	// 计算B的地面法向量
	var chicB = Cesium.Cartographic.fromCartesian(B);
	chicB.height = 0;
	var dB = Cesium.Cartographic.toCartesian(chicB);
	var normaB = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(dB, B, new Cesium.Cartesian3()), new Cesium.Cartesian3())
	// 构造基于B的法向量旋转90度的矩阵
	var Q = Cesium.Quaternion.fromAxisAngle(normaB, Cesium.Math.toRadians(roll));
	var m3 = Cesium.Matrix3.fromQuaternion(Q);
	var m4 = Cesium.Matrix4.fromRotationTranslation(m3);
	
	// 计算A点相对B点的坐标A1
	var A1 = Cesium.Cartesian3.subtract(A, B, new Cesium.Cartesian3());
	//对A1应用旋转矩阵
	var p = Cesium.Matrix4.multiplyByPoint(m4, A1, new Cesium.Cartesian3());
	// 新的A的坐标
	var p2 = Cesium.Cartesian3.add(p, B, new Cesium.Cartesian3());
	return p2;
}


VFG.EModel.prototype.rotatedPointByAngle=function(position_A, position_B, angle) {
    //以B点为原点建立局部坐标系（东方向为x轴,北方向为y轴,垂直于地面为z轴），得到一个局部坐标到世界坐标转换的变换矩阵
    var localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position_B);
    //求世界坐标到局部坐标的变换矩阵
    var worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4());
    //B点在局部坐标的位置，其实就是局部坐标原点
    var localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, position_B, new Cesium.Cartesian3());
    //A点在以B点为原点的局部的坐标位置
    var localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, position_A, new Cesium.Cartesian3());
    //根据数学公式A点逆时针旋转angle度后在局部坐标系中的x,y,z位置
    var new_x = localPosition_A.x * Math.cos(Cesium.Math.toRadians(angle)) + localPosition_A.y *   Math.sin(Cesium.Math.toRadians(angle));
    var new_y = localPosition_A.y * Math.cos(Cesium.Math.toRadians(angle)) - localPosition_A.x * Math.sin(Cesium.Math.toRadians(angle));
    var new_z = localPosition_A.z;
    //最后应用局部坐标到世界坐标的转换矩阵求得旋转后的A点世界坐标
    return Cesium.Matrix4.multiplyByPoint(localToWorld_Matrix, new Cesium.Cartesian3(new_x, new_y, new_z), new Cesium.Cartesian3());
}

VFG.EModel.prototype.destroy = function() {
	let _this=this;
	if(this.primity){
		this.viewer.scene.primitives.remove(this.primity);
	}
	if(this.antennaMap){
		_this.antennaMap.forEach(function (value,key){
			try{
				_this.viewer.entities.removeById(key);
			}catch (e) {
			}finally{
				_this.antennaMap.delete(key);
			}
		});
	}
	delete this.antennaMap
	delete this.orientation
	delete this.position
	delete this.primity
	delete this.options
	delete this.model
    delete this.viewer
	return Cesium.destroyObject(this);
};
